/**
 * Generate code from /{{projectName}}-user/src/main/java/{{packageName}}/{{apis}}/rest/{{apiEntities}}ResourceImpl.java.hbs
 */
// @SkipOverwrite
package cn.ibizlab.api.rest;

import cn.ibizlab.api.dto.AuthLoginDTO;
import cn.ibizlab.api.dto.AuthLoginRequestDTO;
import cn.ibizlab.api.dto.AuthLoginResponseDTO;
import cn.ibizlab.api.dto.AuthTokenDTO;
import cn.ibizlab.api.mapping.AuthUserDTOMapping;
import cn.ibizlab.core.authentication.domain.AuthLogin;
import cn.ibizlab.core.authentication.mapping.AuthInfoMapping;
import cn.ibizlab.core.authentication.service.AuthUserService;
import cn.ibizlab.core.authentication.service.impl.AuthLoginServiceImpl;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.security.JwkStore;
import cn.ibizlab.util.service.AuthenticationUserService;
import cn.ibizlab.util.service.RemoteService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 实体[Auth] 服务对象rest实现
 *
 * @author generator
 */
@Slf4j
public class AuthResourceImpl extends AbstractAuthResource{

    @Autowired
    public AuthUserService authUserService;
    @Autowired
    @Lazy
    public AuthUserDTOMapping authUserDtoMapping;
    @Autowired
    public AuthenticationUserService authenticationUserService;

    @Autowired
    private AuthInfoMapping authUserMapping;


    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "第三方调用，Spring Security 实现 LoadUserByUsername ")
    @RequestMapping(method = {RequestMethod.POST,RequestMethod.GET},value = {"auths/{username}/load_user_by_username","auths/{username}/loaduserbyusername","uaa/{username}/loaduserbyusername"})
    public ResponseEntity<AuthenticationUser> loadUserByUsername
            (@PathVariable("username") String username) {
        return ResponseEntity.status(HttpStatus.OK).body(authenticationUserService.loadUserByUsername(username));
    }


    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "第三方调用，Spring Security 实现 LoadUserAndTokenByUsername ")
    @RequestMapping(method = {RequestMethod.POST},value = {"auths/{username}/loaduserandtokenbyusername"})
    public ResponseEntity<AuthLoginResponseDTO> loadUserAndTokenByUsername
            (@PathVariable("username") String username, @RequestBody AuthLoginDTO dto) {

        return ResponseEntity.status(HttpStatus.OK).body(authLoginResponseDtoMapping.toDto(((AuthLoginServiceImpl)authLoginService).loadUserAndTokenByUsername(username,dto.getOrDefault("focus_refresh_token",false))));
    }

    @Value("${spring.application.name:uaa-api}")
    private String serviceName;

    @Value("${ibiz.rest.basePath.api:/}")
    private String basePath;

    @Autowired
    RemoteService remoteService;

    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "获取用户信息 ")
    @RequestMapping(method = {RequestMethod.GET},value = {"auths/user-info"})
    public ResponseEntity userInfo
            (@RequestParam(value = "access_token",required = false) String access_token, @RequestHeader(value = "Authorization",required = false) String authorization, HttpServletRequest request) {
        return userInfo(access_token,authorization,null,request);
    }

        @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "获取用户信息 ")
    @RequestMapping(method = {RequestMethod.POST},value = {"auths/user-info"})
    public ResponseEntity userInfo
            (@RequestParam(value = "access_token",required = false) String access_token, @RequestHeader(value = "Authorization",required = false) String authorization, @RequestBody(required = false) AuthTokenDTO dto, HttpServletRequest request) {


        String token = authorization;
        if (ObjectUtils.isEmpty(token))
            token = access_token;
        else
            return userInfo();
        if (ObjectUtils.isEmpty(token) && dto!=null)
            token = dto.getAccessToken();

        if(token==null) {
            throw new BadRequestAlertException("未获取到token","Auth","user-info");
        }

        if(!token.startsWith("Bearer"))
            token = "Bearer " +token;

        return ResponseEntity.status(HttpStatus.OK).body(remoteService.getClient(serviceName).get(basePath+"auths/user-info/self",token));
    }


    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "获取用户信息 ")
    @RequestMapping(method = {RequestMethod.GET},value = {"auths/user-info/self"})
    public ResponseEntity<AuthenticationUser> userInfo() {
        return ResponseEntity.status(HttpStatus.OK).body(authenticationUserService.loadUserByUsername(AuthenticationUser.getAuthenticationUser().getUsername()));
    }



    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "获取前端应用上下文数据 ")
    @RequestMapping(method = {RequestMethod.GET,RequestMethod.POST}, value = "appdata")
    public ResponseEntity<Map> getAppData() {
        return ResponseEntity.status(HttpStatus.OK).body(authenticationUserService.getAppData());
    }

    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "获取token公钥 ")
    @RequestMapping(method = {RequestMethod.POST,RequestMethod.GET},value = {"auths/signature_key","auths/signaturekey"})
    public ResponseEntity<String> getSignatureKey(){
        return ResponseEntity.status(HttpStatus.OK).body(authenticationUserService.getSignatureKey());
    }

    @Autowired
    @Lazy
    private JwkStore jwkStore;

    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "获取token公钥pem ")
    @RequestMapping(method = {RequestMethod.POST,RequestMethod.GET},value = {"auths/public_key","auths/publickey"})
    public ResponseEntity<String> getPublicKey(){
        return ResponseEntity.status(HttpStatus.OK).body(jwkStore.getPublicKeyPem());
    }

    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "带token注销登录")
    @RequestMapping(method = {RequestMethod.POST,RequestMethod.GET},value = {"v7/logout", "auths/logout"})
    public ResponseEntity<Boolean> logout() {
        authLoginService.logout(AuthenticationUser.getAuthenticationUser().getUsername());
        return ResponseEntity.ok(true);
    }

    /**
     * Logout 认证接口兼容旧版 注销
     *
     *
     * @param  username
     * @return ResponseEntity<AuthLoginResponseDTO>
     */
    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "兼容旧版 logout ")
    @RequestMapping(method = {RequestMethod.POST,RequestMethod.GET},value = {"v7/{username}/logout","auths/{username}/logout"})
    public ResponseEntity<AuthLoginDTO> logoutByUsername(@PathVariable("username")String username) {
        return super.logoutById(username);
    }

    /**
     * Login 认证接口兼容旧版 登录
     *
     *
     * @param dto dto
     * @return ResponseEntity<AuthLoginResponseDTO>
     */
    @ApiOperation(value = "Login", tags = {"认证接口" },  notes = "兼容旧版 Login ")
    @PostMapping("v7/login")
    public ResponseEntity<AuthLoginResponseDTO> v7login
    (@Validated @RequestBody AuthLoginRequestDTO dto) {
        return login(dto);
    }

    @Override
    public ResponseEntity<AuthLoginResponseDTO> login
            (@Validated @RequestBody AuthLoginRequestDTO dto) {
        try {
            AuthLogin domain = authLoginRequestDtoMapping.toDomain(dto);
            AuthLogin rt = authLoginService.login(domain);
            return ResponseEntity.status(HttpStatus.OK).body(authLoginResponseDtoMapping.toDto(rt));
        } catch (AuthenticationException e) {
            throw new BadRequestAlertException("用户名或密码错误","AuthUser",dto.getLoginName());
        }

    }


    /**
     * OrgInfo 组织机构
     *
     *
     * @param organizationId organizationId
     * @param departmentId departmentId
     * @return ResponseEntity<Map<List<String>>>
     */
    @ApiOperation(value = "OrgInfo", tags = {"认证接口" },  notes = "SysDepartment-OrgInfo ")
    @PostMapping("auths/{organizationId}/{departmentId}/orginfo")
    public ResponseEntity<Map<String,List<String>>> getOrgInfo(@PathVariable("organizationId") String organizationId, @PathVariable("departmentId") String departmentId) {
        return ResponseEntity.status(HttpStatus.OK).body(((AuthLoginServiceImpl)authLoginService).getOrgInfo(organizationId, departmentId));
    }

}
